home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / demos / spectex.c < prev    next >
C/C++ Source or Header  |  1998-12-15  |  7KB  |  268 lines

  1. /* $Id: spectex.c,v 3.1 1998/02/14 18:47:48 brianp Exp $ */
  2.  
  3. /*
  4.  * GLUT demonstration of texturing with specular highlights.
  5.  *
  6.  * When drawing a lit, textured surface one usually wants the specular
  7.  * highlight to override the texture colors.  However, OpenGL applies
  8.  * texturing after lighting so the specular highlight is modulated by
  9.  * the texture.
  10.  *
  11.  * The solution here shown here is a two-pass algorithm:
  12.  *  1. Draw the textured surface without specular lighting.
  13.  *  2. Enable blending to add the next pass:
  14.  *  3. Redraw the surface with a matte white material and only the
  15.  *     specular components of light sources enabled.
  16.  *
  17.  * Brian Paul  February 1997
  18.  */
  19.  
  20.  
  21. /*
  22.  * $Log: spectex.c,v $
  23.  * Revision 3.1  1998/02/14 18:47:48  brianp
  24.  * added OpenGL 1.2 separate specular interpolation support
  25.  *
  26.  * Revision 3.0  1998/02/14 18:42:29  brianp
  27.  * initial rev
  28.  *
  29.  */
  30.  
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <math.h>
  35. #include <GL/glut.h>
  36.  
  37.  
  38. static GLUquadricObj *Quadric;
  39. static GLuint Sphere;
  40. static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
  41. static GLfloat Delta = 1.0;
  42. static GLint Mode = 0;
  43.  
  44. /*static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};*/
  45. /*static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};*/
  46. static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
  47. static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
  48.  
  49.  
  50.  
  51. static void Idle( void )
  52. {
  53.    LightPos[0] += Delta;
  54.    if (LightPos[0]>15.0)
  55.       Delta = -1.0;
  56.    else if (LightPos[0]<-15.0)
  57.       Delta = 1.0;
  58.  
  59.    glutPostRedisplay();
  60. }
  61.  
  62.  
  63. static void Display( void )
  64. {
  65.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  66.  
  67.    glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  68.  
  69.    glPushMatrix();
  70.    glRotatef(90.0, 1.0, 0.0, 0.0);
  71.  
  72.    if (Mode==0) {
  73.       /* Typical method: diffuse + specular + texture */
  74.       glEnable(GL_TEXTURE_2D);
  75.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  76.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  77. #ifdef GL_VERSION_1_2
  78.       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  79. #endif
  80.       glCallList(Sphere);
  81.    }
  82.    else if (Mode==1) {
  83.       /* just specular highlight */
  84.       glDisable(GL_TEXTURE_2D);
  85.       glLightfv(GL_LIGHT0, GL_DIFFUSE, Black);  /* disable diffuse */
  86.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  87. #ifdef GL_VERSION_1_2
  88.       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  89. #endif
  90.       glCallList(Sphere);
  91.    }
  92.    else if (Mode==2) {
  93.       /* diffuse textured */
  94.       glEnable(GL_TEXTURE_2D);
  95.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  96.       glLightfv(GL_LIGHT0, GL_SPECULAR, Black);  /* disable specular */
  97. #ifdef GL_VERSION_1_2
  98.       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  99. #endif
  100.       glCallList(Sphere);
  101.    }
  102.    else if (Mode==3) {
  103.       /* 2-pass: diffuse textured then add specular highlight*/
  104.       glEnable(GL_TEXTURE_2D);
  105.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  106.       glLightfv(GL_LIGHT0, GL_SPECULAR, Black);  /* disable specular */
  107. #ifdef GL_VERSION_1_2
  108.       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  109. #endif
  110.       glCallList(Sphere);
  111.       /* specular highlight */
  112.       glDepthFunc(GL_EQUAL);  /* redraw same pixels */
  113.       glDisable(GL_TEXTURE_2D);
  114.       glEnable(GL_BLEND);  /* add */
  115.       glLightfv(GL_LIGHT0, GL_DIFFUSE, Black);  /* disable diffuse */
  116.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  117.       glCallList(Sphere);
  118.       glDepthFunc(GL_LESS);
  119.       glDisable(GL_BLEND);
  120.    }
  121.    else if (Mode==4) {
  122.       /* OpenGL 1.2's separate diffuse and specular color */
  123.       glEnable(GL_TEXTURE_2D);
  124.       glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
  125.       glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
  126. #ifdef GL_VERSION_1_2
  127.       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  128. #endif
  129.       glCallList(Sphere);
  130.    }
  131.  
  132.    glPopMatrix();
  133.  
  134.    glutSwapBuffers();
  135. }
  136.  
  137.  
  138. static void Reshape( int width, int height )
  139. {
  140.    glViewport( 0, 0, width, height );
  141.    glMatrixMode( GL_PROJECTION );
  142.    glLoadIdentity();
  143.    glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
  144.    glMatrixMode( GL_MODELVIEW );
  145.    glLoadIdentity();
  146.    glTranslatef( 0.0, 0.0, -12.0 );
  147. }
  148.  
  149.  
  150. static void Key( unsigned char key, int x, int y )
  151. {
  152.    switch (key) {
  153.       case 27:
  154.          exit(0);
  155.          break;
  156.    }
  157.    glutPostRedisplay();
  158. }
  159.  
  160.  
  161. static void SpecialKey( int key, int x, int y )
  162. {
  163.    switch (key) {
  164.       case GLUT_KEY_UP:
  165.          break;
  166.       case GLUT_KEY_DOWN:
  167.          break;
  168.    }
  169.    glutPostRedisplay();
  170. }
  171.  
  172.  
  173. static void Init( void )
  174. {
  175.    int i, j;
  176.    GLubyte texImage[64][64][3];
  177.  
  178.    glEnable(GL_LIGHTING);
  179.    glEnable(GL_LIGHT0);
  180.    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
  181.    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
  182.  
  183.    glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
  184.    glMaterialfv(GL_FRONT, GL_SPECULAR, White);
  185.    glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
  186.  
  187.    /* Actually, these are set again later */
  188.    glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
  189.    glLightfv(GL_LIGHT0, GL_SPECULAR, White);
  190.  
  191.    Quadric = gluNewQuadric();
  192.    gluQuadricTexture( Quadric, GL_TRUE );
  193.  
  194.    Sphere= glGenLists(1);
  195.    glNewList( Sphere, GL_COMPILE );
  196.    gluSphere( Quadric, 1.0, 24, 24 );
  197.    glEndList();
  198.  
  199.    glEnable(GL_DEPTH_TEST);
  200.    glEnable(GL_CULL_FACE);
  201.  
  202.    for (i=0;i<64;i++) {
  203.       for (j=0;j<64;j++) {
  204.          int k = ((i>>3)&1) ^ ((j>>3)&1);
  205.          texImage[i][j][0] = 255*k;
  206.          texImage[i][j][1] = 255*(1-k);
  207.          texImage[i][j][2] = 0;
  208.       }
  209.    }
  210.  
  211.    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  212.    glTexImage2D( GL_TEXTURE_2D,
  213.                  0,
  214.                  3,
  215.                  64, 64,
  216.                  0,
  217.                  GL_RGB, GL_UNSIGNED_BYTE,
  218.                  texImage );
  219.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  220.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  221.    glEnable(GL_TEXTURE_2D);
  222.  
  223.    glBlendFunc(GL_ONE, GL_ONE);
  224. }
  225.  
  226.  
  227. static void ModeMenu(int entry)
  228. {
  229.    if (entry==99)
  230.       exit(0);
  231.    Mode = entry;
  232. }
  233.  
  234.  
  235. int main( int argc, char *argv[] )
  236. {
  237.  
  238.    glutInit( &argc, argv );
  239.    glutInitWindowPosition( 0, 0 );
  240.    glutInitWindowSize( 300, 300 );
  241.  
  242.    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  243.  
  244.    glutCreateWindow( "spectex" );
  245.  
  246.    Init();
  247.  
  248.    glutReshapeFunc( Reshape );
  249.    glutKeyboardFunc( Key );
  250.    glutSpecialFunc( SpecialKey );
  251.    glutDisplayFunc( Display );
  252.    glutIdleFunc( Idle );
  253.  
  254.    glutCreateMenu( ModeMenu );
  255.    glutAddMenuEntry("1-pass lighting + texturing", 0);
  256.    glutAddMenuEntry("specular lighting", 1);
  257.    glutAddMenuEntry("diffuse lighting + texturing", 2);
  258.    glutAddMenuEntry("2-pass lighting + texturing", 3);
  259. #ifdef GL_VERSION_1_2
  260.    glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
  261. #endif
  262.    glutAddMenuEntry("Quit", 99);
  263.    glutAttachMenu(GLUT_RIGHT_BUTTON);
  264.  
  265.    glutMainLoop();
  266.    return 0;
  267. }
  268.